library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity VDMERGE is
	Port ( t : in STD_LOGIC_VECTOR (15 downto 0);
		tin : in STD_LOGIC;
		f : in STD_LOGIC_VECTOR (15 downto 0);
		fin : in STD_LOGIC;
		tack : out STD_LOGIC;
		fack : out STD_LOGIC;
		clkin : in STD_LOGIC;
		z : out STD_LOGIC_VECTOR (15 downto 0);
		zstr : out STD_LOGIC;
		zack : in STD_LOGIC;
		c : in STD_LOGIC;
		cin : in STD_LOGIC;
		cack : out STD_LOGIC);
end VDMERGE;

architecture Behavioral of VDMERGE is
	type estados is(juncao, envio);
	begin
		dados: process(clkin, tin, fin, zack, cin)
			variable estado: estados := juncao;
			variable rect: STD_LOGIC := '0';
			variable recf: STD_LOGIC := '0';
			variable recc: STD_LOGIC := '0';
			variable trd: STD_LOGIC_VECTOR(15 downto 0);
			variable fsd: STD_LOGIC_VECTOR(15 downto 0);
			variable zd: STD_LOGIC_VECTOR(15 downto 0);
			variable cd: STD_LOGIC;
		begin
			if clkin'event and clkin = '1' then
				z <= "ZZZZZZZZZZZZZZZZ";
				zstr <= '0';
				tack <= '0';
				fack <= '0';
				cack <= '0';
				case estado is
					when juncao =>
						if tin = '1' then
							trd := t;
							tack <= '1';
							rect := '1';
						end if;
						if fin = '1' then
							fsd := f;
							fack <= '1';
							recf := '1';
						end if;
						if cin = '1' then
							cd := c;
							cack <= '1';
							recc := '1';
						end if;
						if rect = '1' and recf = '1' and recc = '1' then
							if cd = '1' then
								zd := trd;
							else
								zd := fsd;
							end if;
							rect := '0';
							recf := '0';
							recc := '0';
							estado := envio;
						end if;
					when envio =>
						if zack = '1' then
							estado := juncao;
						else
							z <= zd;
							zstr <= '1';
						end if;
				end case;
			end if;
	end process dados;
end Behavioral;